package com.gitee.auth;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;

/**
 * Created by EalenXie on 2021/6/30 14:58
 */
public class OauthTools {

    private OauthTools() {
    }


    public static final ObjectMapper OBJECTMapper;

    static {
        OBJECTMapper = new ObjectMapper();
        OBJECTMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * 是否认证
     */
    public static boolean isAuthenticated() {
        Authentication authentication = getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) return false;
        return (authentication.getPrincipal() instanceof OauthUserDetails);
    }

    public static UserInfo getUserInfo() {
        Object res = getOauth2Principal();
        if (res instanceof OauthUserDetails) {
            UserInfo user = new UserInfo();
            BeanUtils.copyProperties(res, user);
            return user;
        }
        throw new InsufficientAuthenticationException("Can not resolve user_info by token");
    }

    public static Authentication getAuthentication() {
        return SecurityContextHolder.getContext().getAuthentication();
    }

    public static Object getOauth2Principal() {
        Authentication authentication = getAuthentication();
        if (authentication == null) throw new InsufficientAuthenticationException("Not a valid authenticated user");
        return authentication.getPrincipal();
    }

    public static Object getDetails() {
        Authentication authentication = getAuthentication();
        if (authentication instanceof OAuth2Authentication) {
            OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) authentication;
            Object details = oAuth2Authentication.getDetails();
            if (details instanceof OAuth2AuthenticationDetails) {
                OAuth2AuthenticationDetails authenticationDetails = (OAuth2AuthenticationDetails) details;
                return authenticationDetails.getDecodedDetails();
            }
        }
        return authentication.getDetails();
    }


}